
import Foundation
import UIKit
import CommonCrypto
 func LS(_ s : String)->String
{
    return NSLocalizedString(s, comment: "")
}
//MARK: - 十进制、十六进制转换
public extension String
{
    //MARK: - 十六进制转换成十进制
    ///十六进制转换成十进制
    func toDecimal()-> Int
    {
        var sum = 0
        let str:String = self.uppercased()
        for i in str.utf8{
            sum = sum * 16 + Int(i) - 48//0-9:从48开始
            if i >= 65{//a-z:从65开始
                sum -= 7
            }
        }
        
        ///去除。“-”符号
        if sum > Int32.max {
            let realNum = sum - 1
            let negation = ~realNum
            sum = Int(-Int32(negation & 0xff))
        }
        return sum
    }
    ///方法2: 十六进制转换成十进制
    func toDecimal2()->Int{
        let scanner = Scanner(string: self)
        var num: UInt64 = 0
        scanner.scanHexInt64(&num)
        return Int(num)
    }
    
    //MARK: - 十进制转换成十六进制
    ///方法1:十进制转换成十六进制
    func toHex() ->NSString
    {
        return String(self.intValue(),radix:16) as NSString
    }
    ///方法2:十进制转换成十六进制，并自动补0
    func toHex2()->String{
        guard let num = Int(self) else {return ""}
        return String(format: "%02X", num)
    }
    
    //MARK: - 16进制字符串转data
    ///16进制字符串转data
    func hexadecimal() -> Data? {
        var data = Data(capacity: self.count / 2)
        
        let regex = try! NSRegularExpression(pattern: "[0-9a-f]{1,2}", options: .caseInsensitive)
        regex.enumerateMatches(in: self, range: NSMakeRange(0, utf16.count)) { match, flags, stop in
            let byteString = (self as NSString).substring(with: match!.range)
            var num = UInt8(byteString, radix: 16)!
            data.append(&num, count: 1)
        }
        
        guard data.count > 0 else { return nil }
        
        return data
    }
    
    //MARK: - 16进制字符串转换成2进制字符串
    ///16进制字符串转换成2进制字符串
    func hexToBin()->String{
        guard let decimalValue = Int(self, radix:16) else{return ""}
        return String(decimalValue, radix: 2)///方法1
        //return String(format: "%b", decimalValue)///方法2
    }
    
    ///2进制转换成16进制字符串
    func binToHex()->String{
        guard let decimalValue = Int(self, radix: 2) else{return ""}
        return String(decimalValue, radix: 16)///方法1
        //return String(format: "%.2x", decimalValue)///方法2
    }
    
    //MARK: - String -> utf16的unicode
    /// String -> utf16的unicode
    /// - Parameter bytes: 需要转换的字符串，最大字节bytes数
    /// - Returns:string的utf16的unicode
    func utf16Unicode(_ bytes:Int=0)->String{
        var utf_title = ""
        ///string->utf16
        let utf16_title = self.utf16
        ///当长度小于0时，自动取字符串的全长度，一个字符串，2bytes
        let max_length = bytes <= 0 ? self.count * 2 : bytes
        for s in utf16_title{
            ///汉字的unicode有4位，英文的unicode是2位，不足4位，前面补0
            guard let num = Int("\(s)") else {return ""}
            utf_title += String(format: "%04X", num)
            ///每次传输不能超过最大限制的字节
            if utf_title.count / 2 >= max_length { break}
        }
        return utf_title
    }
    //MARK: - String -> ASCII码
    ///字符串转ASCII码
    var ascii : [Int]{
        return self.unicodeScalars.compactMap { $0.isASCII ? Int($0.value) : nil }
    }
    
    //MARK: - 16进制字符串 -> [Uin8]
    ///16进制字符串，转换成 [Uin8]
    ///"0F0304" -> [15,3,4]
    var bytes : [UInt8]{
        var bytes = [UInt8]()
        var currentIndex = self.startIndex
        
        while currentIndex < self.endIndex {
            let nextIndex = self.index(currentIndex, offsetBy: 2)
            let byteString = self[currentIndex..<nextIndex]
            if let byte = UInt8(byteString, radix: 16) {
                bytes.append(byte)
            }
            currentIndex = nextIndex
        }
        
        return bytes
    }
}


//MARK: - 十六进制字符串转换成颜色
public extension String
{
    
    /// 将十六进制颜色转换成UIColor
    /// - Returns: UIColor
    func color() -> UIColor
    {
        self.color(1.0)
    }
    
    /// 将十六进制颜色转换成UIColor
    /// - Parameter alpha: 透明值
    /// - Returns: UIColor
    func color(_ alpha : Float) -> UIColor
    {
        var cString = self.uppercased().trimmingCharacters(in: CharacterSet.whitespacesAndNewlines)
        
        if (cString.count < 6)
        {
            return .white
        }
        if cString.hasPrefix("0X")
        {
            cString = cString[2...cString.count]
        }
        if cString.hasPrefix("#")
        {
            cString = cString[1...cString.count]
        }
        if cString.count != 6
        {
            return .white
        }
        
        //R.G.B
        let rString = cString[0...1]
        let gString = cString[2...3]
        let bString = cString[4...5]
        
        //存储转换后的数值
        var r : UInt64 = 0, g : UInt64  = 0, b : UInt64 = 0
        Scanner(string: rString).scanHexInt64(&r)
        Scanner(string: gString).scanHexInt64(&g)
        Scanner(string: bString).scanHexInt64(&b)
        return UIColor(red: CGFloat(r)/255, green: CGFloat(g)/255, blue: CGFloat(b)/255.0, alpha:CGFloat(alpha))
    }
    
    /// 获取某个下标的字符
    subscript(of index : Int) -> String
    {
        if index < 0 || index >= self.count
        {
            return ""
        }
        let s = self as NSString
        return s.substring(with: NSMakeRange(index, 1)) as String
    }
    /// 获取[1...3]的字符
    subscript( r : ClosedRange<Int>) -> String
    {
        let start = index(startIndex, offsetBy:max(r.lowerBound, 0))
        let end = index(startIndex, offsetBy: min(r.upperBound, count - 1))
        return String(self[start...end])
    }
    
    /// 替换[1...3]的字符
    ///“123”.replace(r: 1...2, content:“456”)) = 1456
    /// - Parameters:
    ///   - r: ClosedRange 1...3
    ///   - content: 替换的内容
    /// - Returns: 字符串
    mutating func replace( r : ClosedRange<Int>, content:String)
    {
        let start = index(startIndex, offsetBy:max(r.lowerBound, 0))
        let end = index(startIndex, offsetBy: min(r.upperBound, count - 1))
        self.replaceSubrange(start...end, with: content)
    }
    
    /// 截取字符
    /// - Parameters:
    ///   - start: 开始下标
    ///   - count: 截取长度
    /// - Returns: 字符串
    func subString(_ start : Int, _ count : Int) -> String
    {
        let startIndex = index(startIndex, offsetBy:max(start, 0))
        let endIndex = index(startIndex, offsetBy:min(start + count, count))
        return String(self[startIndex...endIndex])
    }
    
    
    /// 字符串不足指定的位数时候，自动补全
    /// - Parameters:
    ///   - count: 指定显示的位数
    ///   - addString: 自动补全的字符串
    /// - Returns: 返回补全后的字符串，例如000001
    func fixString(_ count : Int, _ addString : String)->String
    {
        var temp = self
        for _ in 0..<(count-self.count)
        {
            temp = "\(addString)"+temp
        }
        return temp
    }
}

//MARK: - 字符串转int
public extension String
{
    func intValue() -> Int
    {
        return Int((self as NSString).intValue)
    }
    
    func boolValue()->Bool
    {
        assert(self.isNumber(),"\(self)不是一个数字")
        return Bool((self as NSString).boolValue)
    }
    func floatValut() -> CGFloat
    {
        return CGFloat((self as NSString).floatValue)
    }
}

//MARK: - 字符串的一些判断
public extension String
{
    /// 是否手机号码
    func isMobile()-> Bool{
        let match = "1[3456789]([0-9]){9}"
        let pre : NSPredicate = NSPredicate(format: "SELF MATCHES %@",match)
        return pre.evaluate(with: self)
    }
    /// 是否纯数字
    func isNumber() -> Bool
    {
        let numRegex = "[0-9]*"
        let pre : NSPredicate = NSPredicate(format: "SELF MATCHES %@",numRegex)
        return pre.evaluate(with: self)
    }
    ///是否是纯汉字
    func isChinese()-> Bool
    {
        let match = "(^[\u{4e00}-\u{9fa5}]+$)"
        let pre : NSPredicate = NSPredicate(format: "SELF MATCHES %@",match)
        return pre.evaluate(with: self)
    }
    ///是否是字母和阿拉伯数字混合
    func isNumberOrAlphabet()->Bool{
        let match = "^[a-zA-Z0-9]+$"
        let pre : NSPredicate = NSPredicate(format: "SELF MATCHES %@",match)
        return pre.evaluate(with: self)
    }
    
    func isNumOrChineseOrEnglish()->Bool{
        let match = "^[a-z0-9A-Z\u{4e00}-\u{9fa5}]+$"
        let pre : NSPredicate = NSPredicate(format: "SELF MATCHES %@",match)
        return pre.evaluate(with: self)
    }
    ///判断是不是空格
    func isSpace() -> Bool {
        let regex = "^[\\s]+$"
        let predicate = NSPredicate(format: "SELF MATCHES %@", regex)
        return predicate.evaluate(with: self)
    }
    ///是否空的字符串
    func isNull() -> Bool
    {
        if self.isKind(of:NSString.classForCoder()){
            return self.count == 0
        }
        for i in 0..<self.count
        {
            if (self[of:i] == " ") ==  false {
                return false
            }
        }
        return true
    }
    
    ///是否整数
    func isInt() -> Bool {
        let scan: Scanner = Scanner(string:self)
        var val:Int = 0
        return scan.scanInt(&val) && scan.isAtEnd
    }
    ///是否浮点型
    func isFloat()->Bool{
        let scan: Scanner = Scanner(string:self)
        var val:Float = 0
        return scan.scanFloat(&val) && scan.isAtEnd
    }
    ///判断是否字母开头，并且长度在x-y位(用于账号注册的时候)
    func isAccount(_ min:Int,_ max:Int)->Bool{
        let match = String(format: "^([a-z]|[a-zA-Z0-9]){%d,%d}$",min,max)
        let pre : NSPredicate = NSPredicate(format: "SELF MATCHES %@",match)
        return pre.evaluate(with: self)
    }
    ///判断是否身份证
    func isIDCart()->Bool{
        if self.count != 18 {return false}
        let match = "^(^[1-9]\\d{7}((0\\d)|(1[0-2]))(([0|1|2]\\d)|3[0-1])\\d{3}$)|(^[1-9]\\d{5}[1-9]\\d{3}((0\\d)|(1[0-2]))(([0|1|2]\\d)|3[0-1])((\\d{4})|\\d{3}[Xx])$)$"
        let pre : NSPredicate = NSPredicate(format: "SELF MATCHES %@",match)
        //如果通过该验证，说明身份证格式正确，但准确性还需计算
        if pre.evaluate(with: self){
            //** 开始进行校验 *//
            //将前17位加权因子保存在数组里
            let idArray = ["7","9","10","5","8","4","2","1","6","3","7","9","10","5","8","4","2"]
            //这是除以11后，可能产生的11位余数、验证码，也保存成数组
            let idYArray = ["1","0","10","9","8","7","6","5","4","3","2"]
            //用来保存前17位各自乖以加权因子后的总和
            var idCardWiSum = 0
            for i in 0..<17{
                let subStrIndex = self.subString(i, 1).intValue()
                let idCardWiIndex = idArray[i].intValue()
                idCardWiSum += subStrIndex * idCardWiIndex
            }
            //计算出校验码所在数组的位置
            let idCardMod = idCardWiSum % 11
            let idCardLast = self.subString(17, 1)
            //如果等于2，则说明校验码是10，身份证号码最后一位应该是X
            if idCardMod == 2{
                return idCardLast == "X"
            }else{
                //用计算出的验证码与最后一位身份证号码匹配，如果一致，说明通过，否则是无效的身份证号码
                return idCardLast == idYArray[idCardMod]
            }
            return true
        }
        return false
    }
    
    ///判断是否是邮箱
    func isEmail()->Bool{
        let match = String(format: "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}")
        let pre : NSPredicate = NSPredicate(format: "SELF MATCHES %@",match)
        return pre.evaluate(with: self)
    }
}

//MARK: - 日期
public extension String
{
    ///时间戳(字符串形式)俺需要的格式，转换成日期格式(MM/dd，或者yy/MM/dd/)
    func transToDate(_ format : String)->String
    {
        let timeInterval = TimeInterval(self.intValue())
        let date = Date(timeIntervalSince1970: timeInterval)
        let dateformatter = DateFormatter()
        dateformatter.dateFormat = format
        return dateformatter.string(from: date)
    }
    
    
    /// 日期形式转换成时间戳
    /// - Parameter format: 日期形式MM/dd，或者yy/MM/dd/
    func transToStamp(_ format:String)->Int
    {
        let dateFormatter = DateFormatter()
        dateFormatter.timeZone = TimeZone.current
        dateFormatter.dateFormat = format
        let date = dateFormatter.date(from:self)
        return Int(date?.timeIntervalSince1970 ?? 0)
    }
    
    ///具体秒数（非时间戳）转换成24小时格式
    func secTranToTime()->String
    {
        let num = self.intValue()
        let min = num / 60 % 60
        let second = num % 60
        let hour = num / 3600
        return String(format:"%.2ld:%.2ld:%.2ld", hour,min,second)
    }
}


public extension String
{
    ///富文本
    func attri(_ font:UIFont, _ color:UIColor)->NSMutableAttributedString
    {
        return NSMutableAttributedString(string:self, attributes:[.font:font, .foregroundColor:color])
    }
    
    func kjson()->String
    {
        var s = self
        s = s.replacingOccurrences(of: "[", with: "")
        s = s .replacingOccurrences(of:"]", with: "")
        s = s.replacingOccurrences(of: "\"", with: "")
        return s
    }
}


//MARK: - 字符串生成图片
public extension String{
    var img : UIImage? { return UIImage(named:self) ?? nil}
}


//MARK: - 文本渐变色效果
public extension String{
    func setGradientText(colors: [UIColor], bounds:CGRect, font:UIFont)->NSAttributedString {
            let gradientText = self
            let attributedText = NSMutableAttributedString(string: gradientText)
            
            let gradientLayer = CAGradientLayer()
            gradientLayer.frame = bounds
            gradientLayer.colors = colors.map { $0.cgColor }
            gradientLayer.startPoint = CGPoint(x: 0, y: 0)
            gradientLayer.endPoint = CGPoint(x: 0, y: 1)
            
            UIGraphicsBeginImageContextWithOptions(gradientLayer.bounds.size, false, 0)
            gradientLayer.render(in: UIGraphicsGetCurrentContext()!)
            let gradientImage = UIGraphicsGetImageFromCurrentImageContext()
            UIGraphicsEndImageContext()
            
        attributedText.addAttribute(.foregroundColor, value: UIColor(patternImage: gradientImage!), range: NSRange(location: 0, length: gradientText.count))
        attributedText.addAttribute(.font, value:font , range: NSRange(location: 0, length: gradientText.count))
           return attributedText
        }
}
